#!/usr/bin/env python
#coding=utf-8


import datetime
import pandas as pd
from app.bill.models.oa_asset import OaAsset
from app.celery_task.models.celery_task import CeleryTask
from common.oa_platform import OaPlatform


from sqlalchemy.orm import Session
from core.response import resp_500
from core.logger import logger
from common.utils import is_empty


class OaAssetHandler(object):
    def __init__(self):
        pass


    def get_oa_asset_search(self, db: Session, page: int, per_page: int, field: str, value: str):
        """
        oa资产事件记录表, 根据表字段-模糊查询, 获取事件数据
        """
        try:
            field_info = {field: value}
            order_info = {"application_time": "desc"}
            result = OaAsset.filter_by_field_search(db, page, per_page, field_info, order_info)
            if not result:
                logger.warning(f"get oa asset search, result is null => {field}:{value}")
                return False, None

        except Exception as e:
            message = f"get oa asset search by {field}:{value} error"
            logger.exception(f"{message} => {e}")
            return resp_500(message)

        return True, result



    def get_oa_asset_match(self, db: Session, page: int, per_page: int, field: str, value: str):
        """
        oa资产事件记录表, 根据表字段-完全查询, 获取资产事件
        """
        try:
            result = OaAsset.filter_by_field_match(db, page, per_page, {field: value})
            if not result:
                logger.warning(f"get oa asset match failed, result is null => {field}:{value}")
                return True, []

        except Exception as e:
            message = f"get oa asset match by {field}:{value} error"
            logger.exception(f"{message} => {e}")
            return resp_500(message)

        return True, result


    def get_oa_asset_name_by_month(self, db: Session, asset_type: str, asset_name: str, month: str):
        """
        oa资产事件记录表, 根据信息条目查询, 获取资产事件
        """
        try:
            result = OaAsset.get_asset_name_by_month(db, asset_type, asset_name, month)
            if not result:
                logger.warning(f"get oa asset name by month failed, result is null")
                return True, []
            
        except Exception as e:
            message = f"get oa asset name by month error"
            logger.exception(f"{message} => {e}")
            return resp_500(message)

        return True, result


    def add_oa_asset(self, db: Session, data: dict):
        """
        增加oa资产事件记录信息
        """
        try:
            # 添加到数据库
            result = OaAsset.add(db, data)
            if not result:
                logger.error(f"add oa asset to database failed")
                return False
        except Exception as e:
            message = f"add oa asset error"
            logger.exception(f"{message} data:{data} => {e}")
            return resp_500(message)

        return True



    def update_event(self, db: Session, data: dict):
        """
        修改oa资产事件记录信息
        """
        try:
            oa_asset_object = OaAsset.get_object_by_uuid(db, data["uuid"])
            if not oa_asset_object:
                # 如果不存在， 则异常返回
                logger.error(f"update oa asset failed, uuid:{data['uuid']} not exist")
                return False

            # 更新数据库
            result = OaAsset.update(db, data)
            if not result:
                logger.error(f"update oa asset to database failed")
                return False
        except Exception as e:
            message = f"update oa asset error "
            logger.exception(f"{message} data:{data} => {e}")
            return resp_500(message)

        return True



    def delete_event(self, db: Session, data: dict):
        """
        删除oa资产事件记录信息
        """
        try:
            oa_asset_object = OaAsset.get_object_by_uuid(db, data['uuid'])
            if not oa_asset_object:
                # 如果不存在， 则异常返回
                logger.error(f"delete oa asset failed, uuid:{data['uuid']} not exist")
                return False

            # 删除
            OaAsset.delete_object_by_uuid(db, data['uuid'])
        except Exception as e:
            message = f"delete oa asset error"
            logger.exception(f"{message} data:{data} => {e}")
            return resp_500(message)

        return True



    def post_oa_asset_workorder_task(self, db: Session, data: dict):
        """
        启动同步工单信息的异步任务
        """
        try:
            # 启动异步任务
            from app.bill.task import oa_asset_from_work_order_async
            # 判断任务是否已经启动，控制只有一个任务在跑。 如果任务可以多个同时进行，则无需这一步判断。
            task_name = oa_asset_from_work_order_async.name.split(".")[-1]
            if CeleryTask.is_progress_on_name(db, task_name):
                logger.error(f"task: {task_name} was stared")
                return False

            task = oa_asset_from_work_order_async.delay(data["month"])
            task_data = {
                "name": task_name,
                "tid": task.id,
                "state": task.state
            }
        except Exception as e:
            message = f"start oa asset workorder task error, month:{data['month']}"
            logger.exception(f"{message} => {e}")
            return resp_500(message)

        logger.info(f"add task: {task_name} success")
        return task_data




    def task_update_from_work_order_handle(self, db: Session, month: str):
        """
        更新工单事件信息的处理函数
        """
        try:
            if not month:
                # 如果没指定，则为上月
                last_month = datetime.date(datetime.date.today().year, datetime.date.today().month, 1) - datetime.timedelta(days=1)
                month = last_month.strftime("%Y-%m")
            else:
                year_month = datetime.date(int(month.split("-")[0]), int(month.split("-")[1]), 1)
                month = year_month.strftime("%Y-%m")

            # 清理数据库中的工单数据
            OaAsset.delete_by_month(db, month)
            
            # 从oa获取云资源所有个工单数据
            oa_platform = OaPlatform()
            asset_infos = oa_platform.get_asset_infos(month)
            
            # 添加到数据库
            OaAsset.saves(db, asset_infos)
        except Exception as e:
            logger.error(f"update oa asset error=>{e}")
            return False

        logger.info(f"update oa asset success")
        return True




